
package com.feib.ebilling.job.service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Properties;

import javax.annotation.Resource;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.enterprisedt.net.ftp.FileTransferClient;

import com.feib.ebilling.job.util.CreateZip;

/**
 * @title (#)FtpService.java<br>
 * @description <br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/12/11 create by Jimmy Liu<br>
 */
@Service("ftpService")
@Scope(value=BeanDefinition.SCOPE_PROTOTYPE)
public class FtpService extends BaseService {

    /* 讀取FTP設定檔 */
    @Resource(name="ftpProperties")
    private Properties ftpProperties;

    private boolean bRetryFTP = false;

    public boolean retryGetFtpFile(String sChanel ,String sFileName) {

        /* FTP Retry 次數 */
        int iRetryCnt = Integer.parseInt(ftpProperties.getProperty(sChanel + "#RetryTimes"));            
        boolean bRtn = false;
        for (int i=1; i<=iRetryCnt; i++){
        	if (!sChanel.equals("POST")){
        		logger.info("FTP Get File..");
                bRtn = getFTPFile(sChanel, sFileName, i);
        	}else{
        		/* 郵局走SSL */
        		if (ftpProperties.getProperty(sChanel + "#SSL").equals("true")){
        			logger.info("FTP SSL Get File..");
        		    bRtn = getFTPSSLFile(sChanel, sFileName, i);
        		}else{
        			logger.info("FTP Get File..");
        			bRtn = getFTPFile(sChanel, sFileName, i);
        		}
        	}
            if (bRtn){
                /* 成功下載 */                              
                break;
            }       
        }   
        if (bRetryFTP){
            /* 超過Retry上限  */
            logger.error("Retry FTP Get File Fail..");
            bRtn = false;
        }                       
        return bRtn;
    }       
    
    /* 取得FTP檔案 FTPS Server */
    public boolean getFTPSSLFile(String sChanel ,String sFileName, int iRetry) {
    	         
         try {
             /* 取得FTP設定 */
             String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");
             String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
             String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
             String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
             String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");

             logger.info("FTP Server Connect : {}", host);
             logger.info("FTP User Name : {}", username);
             logger.info("FTP Local Directory : {}", localFolder);
             logger.info("FTP Remote Directory : {}", remoteFolder);
             logger.info("FTP Retry Times : {}", iRetry);

             logger.info("FTP File = {}", sFileName.toUpperCase());
             /* 刪除舊檔案 */
             File uploadedFile = new File(localFolder + "\\" + sFileName);
             if(uploadedFile.exists()){
                 uploadedFile.delete();
                 logger.info("Delete {}/{}", localFolder, sFileName);
             }  
             logger.info("Start FTP SSL..."); 
             FtpSSLService ftps = new FtpSSLService();
 			 if (ftps.getFile(sFileName, remoteFolder, host, username, password, localFolder)){
 				 /* 儲存檔案名稱 */
 	             logger.info("Download {} to {}", sFileName, localFolder);
 			 }else{
 				 logger.info("Fail to download  to  folder " + localFolder);
 			 }
             /* 已完成下傳，不再Retry */      
             bRetryFTP = false;
             return true;   
         } catch (Exception ex) {            
             logger.info(ex.toString(), ex);
             logger.info("Retry FTP {}", iRetry);
             /* 未完成下傳，需要Retry */ 
             bRetryFTP = true;
             return false;                                       
         } 
        
    }
    
    /* 刪除FTP檔案 FTP Server */
    public boolean delFTPFile(String sChanel ,String sFileName, int iRetry) {

        FileTransferClient ftp = null;
        
        try {

            /* 取得FTP設定 */
            String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");
            String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
            String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
            String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
            String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");

            logger.info("FTP Server Connect : {}", host);
            logger.info("FTP User Name : {}", username);
            logger.info("FTP Local Directory : {}", localFolder);
            logger.info("FTP Remote Directory : {}", remoteFolder);
            logger.info("FTP Retry Times : {}", iRetry);

            /* Free Java FTP library edtFTPj http://www.enterprisedt.com/index.html */
            ftp = new FileTransferClient();
            ftp.setRemoteHost(host);
            ftp.setUserName(username);
            ftp.setPassword(password); 
            ftp.connect();
            if (ftp.isConnected()){
                logger.info("FTP File = {}", sFileName.toUpperCase());               
                /* 切換FTP目錄  */
                if (remoteFolder != null && !remoteFolder.trim().equals("")){
                    ftp.changeDirectory(remoteFolder);
                    logger.info("Directory change to {}", ftp.getRemoteDirectory());
                }
                logger.info("File {} size is {} Bytes", sFileName, ftp.getSize(sFileName));
                /* 刪除檔案 */
                ftp.deleteFile(sFileName);
                /* 儲存檔案名稱 */
                logger.info("delete {} ", sFileName);
            }   
            ftp.disconnect(true);
            /* 已完成刪除，不再Retry */      
            bRetryFTP = false;
            return true;   
        } catch (Exception ex) {
            try {    
            	logger.info("Disconnect ftp");
                if (null != ftp && ftp.isConnected())
                    ftp.disconnect(true);
                
                ftp = null;
            }
            catch (Exception e) {            	
            	logger.info(ex.toString(), ex);
            }
            logger.info(ex.toString(), ex);
            logger.info("Retry FTP {}", iRetry);
            /* 未完成刪除，需要Retry */ 
            bRetryFTP = true;
            return false;                                       
        }
    }
    

    /* 取得FTP檔案 FTP Server */
    public boolean getFTPFile(String sChanel ,String sFileName, int iRetry) {


        FileTransferClient ftp = null;
        
        try {

            /* 取得FTP設定 */
            String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");
            String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
            String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
            String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
            String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");

            logger.info("FTP Server Connect : {}", host);
            logger.info("FTP User Name : {}", username);
            logger.info("FTP Local Directory : {}", localFolder);
            logger.info("FTP Remote Directory : {}", remoteFolder);
            logger.info("FTP Retry Times : {}", iRetry);

            /* Free Java FTP library edtFTPj http://www.enterprisedt.com/index.html */
            ftp = new FileTransferClient();
            ftp.setRemoteHost(host);
            ftp.setUserName(username);
            ftp.setPassword(password); 
            ftp.connect();
            if (ftp.isConnected()){
                logger.info("FTP File = {}", sFileName.toUpperCase());
                /* 刪除舊檔案 */
                File uploadedFile = new File(localFolder + "\\" + sFileName);
                if(uploadedFile.exists()){
                    uploadedFile.delete();
                    logger.info("Delete {}/{}", localFolder, sFileName);
                }
                /* 切換FTP目錄  */
                if (remoteFolder != null && !remoteFolder.trim().equals("")){
                    ftp.changeDirectory(remoteFolder);
                    logger.info("Directory change to {}", ftp.getRemoteDirectory());
                }

                logger.info("File {} size is {} Bytes", sFileName, ftp.getSize(sFileName));
                /* 下載檔案 */
                ftp.downloadFile(localFolder, sFileName);
                /* 儲存檔案名稱 */
                logger.info("Download {} to {}", sFileName, localFolder);
            }   
            ftp.disconnect(true);
            /* 已完成下傳，不再Retry */      
            bRetryFTP = false;
            return true;   
        } catch (Exception ex) {
            try {    
            	logger.info("Disconnect ftp");
                if (null != ftp && ftp.isConnected())
                    ftp.disconnect(true);
                
                ftp = null;
            }
            catch (Exception e) {            	
            	logger.info(ex.toString(), ex);
            }
            logger.info(ex.toString(), ex);
            logger.info("Retry FTP {}", iRetry);
            /* 未完成下傳，需要Retry */ 
            bRetryFTP = true;
            return false;                                       
        }
    }
    
    
    
    /* 上傳FTP檔案 FTP Server */
    public boolean putFTPFile(String sChanel ,String processDate, String sContent, String sFileName) {

        FileTransferClient ftp = null;
        
        try {

            /* 取得FTP設定 */
            String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");            
            String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
            String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
            String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
            String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");
            
            if (localFolder == null || localFolder.equals("")) {
            	/* 預設檔暫存路徑 
            	 * 正式套是D，本機是C*/
            	localFolder = "C:\\eBilling\\writeoff";
            }
            
            /* 檢核是否需要回饋檔案ftp.properties中設定  */
            if (host == null || host.equals("")) {
            	logger.info("{} 未設定回饋FTP Server IP!", sChanel);
            	return false;
            }else{
            	/* Log FTP 位置 */
                logger.info("FTP Server Connect : {}", host);
                logger.info("FTP User Name : {}", username);
                logger.info("FTP Local Directory : {}", localFolder);
                logger.info("FTP Remote Directory : {}", remoteFolder);
	            /* 刪除舊檔案 */
	            File uploadedFile = new File(localFolder + "\\" + sFileName);
	            if(uploadedFile.exists()){
	                uploadedFile.delete();
	                logger.info("Delete {}", localFolder + "\\" + sFileName);
	            }	            
	            /* 寫入新檔案 */            
	            File file = new File(localFolder + "\\" + sFileName);                        
	            BufferedWriter bufWriter = new BufferedWriter(
	            		 new OutputStreamWriter(new FileOutputStream(file,false), "Big5"));
	            bufWriter.write(sContent);
	            bufWriter.close();
	            logger.info("Write File = {}", localFolder + "\\" + sFileName);	
            }
            
            /* Free Java FTP library edtFTPj http://www.enterprisedt.com/index.html */
            ftp = new FileTransferClient();
            ftp.setRemoteHost(host);
            ftp.setUserName(username);
            ftp.setPassword(password); 
            ftp.connect();
            if (ftp.isConnected()){
                logger.info("FTP File = {}", localFolder + "\\" + sFileName);                
                /* 切換FTP目錄  */
                if (remoteFolder != null && !remoteFolder.trim().equals("")){
                    ftp.changeDirectory(remoteFolder);
                    logger.info("Directory change to {}", ftp.getRemoteDirectory());
                }                
                /* 上傳載檔案 */
                ftp.uploadFile(localFolder + "\\" + sFileName, sFileName);
                /* 儲存檔案名稱 */
                logger.info("Upload {} to {}",localFolder + "\\" + sFileName , sFileName);
            }   
            ftp.disconnect(true);            
            return true;   
        } catch (Exception ex) {
            try {    
            	logger.info("Disconnect ftp");
                if (null != ftp && ftp.isConnected())
                    ftp.disconnect(true);                
                ftp = null;
            }
            catch (Exception e) {
            	logger.error(ex.toString(), ex);
            }
            logger.error(ex.toString(), ex);
            return false;                                       
        }
    }
    
    /* 加密FTP檔案 FTP Server */
    public boolean zipFTPFile(String sChanel ,String sFileName) {

        FileTransferClient ftp = null;
        
        try {

            /* 取得FTP設定 */
            String host  = ftpProperties.getProperty(sChanel + "#FTPServerIP");            
            String username = ftpProperties.getProperty(sChanel + "#FTPUserName");
            String password = ftpProperties.getProperty(sChanel + "#FTPPassword");
            String localFolder = ftpProperties.getProperty(sChanel + "#LocalFolder");
            String remoteFolder = ftpProperties.getProperty(sChanel + "#RemoteFolder");
            String zippassword = ftpProperties.getProperty(sChanel + "#Zip");
            
            if (localFolder == null || localFolder.equals("")) {
            	/* 預設檔暫存路徑 
            	 * 正式套是D，本機是C*/
            	localFolder = "C:\\eBilling\\writeoff";
            }
            
            /* 檢核是否需要回饋檔案ftp.properties中設定  */
            if (host == null || host.equals("")) {
            	logger.info("{} 未設定回饋FTP Server IP!", sChanel);
            	return false;
            }else{
            	/* Log FTP 位置 */
                logger.info("FTP Server Connect : {}", host);
                logger.info("FTP User Name : {}", username);
                logger.info("FTP Local Directory : {}", localFolder);
                logger.info("FTP Remote Directory : {}", remoteFolder);
                if (zippassword != null) {
	                CreateZip zip = new CreateZip();
	                /* 檔案壓成zip並加密 */
	                zip.CreateZipWithOutputStreams(localFolder + "\\" + sFileName, zippassword);
	                /* Free Java FTP library edtFTPj http://www.enterprisedt.com/index.html */
	                ftp = new FileTransferClient();
	                ftp.setRemoteHost(host);
	                ftp.setUserName(username);
	                ftp.setPassword(password); 
	                ftp.connect();
	                if (ftp.isConnected()){
	                    logger.info("FTP File = {}", localFolder + "\\" + sFileName);                
	                    /* 切換FTP目錄  */
	                    if (remoteFolder != null && !remoteFolder.trim().equals("")){
	                        ftp.changeDirectory(remoteFolder);
	                        logger.info("Directory change to {}", ftp.getRemoteDirectory());
	                    }                
	                    /* 上傳載檔案 */
	                    ftp.uploadFile(localFolder + "\\" + sFileName.substring(0, sFileName.length() - 4) + ".zip",
	                    		       sFileName.substring(0, sFileName.length() - 4) + ".zip");                
	                    /* 儲存檔案名稱 */
	                    logger.info("Upload {} to {}",localFolder + "\\" + sFileName ,
	                    		       sFileName.substring(0, sFileName.length() - 4) + ".zip");
	                    /* 刪除未加密檔案 */
	                    ftp.deleteFile(sFileName);
	                    logger.info("Delete {} ", sFileName);
	                }   
	                ftp.disconnect(true);
                }
	        }                       
            return true;   
        } catch (Exception ex) {
            try {    
            	logger.info("Disconnect ftp");
                if (null != ftp && ftp.isConnected())
                    ftp.disconnect(true);                
                ftp = null;
            }
            catch (Exception e) {
            	logger.error(ex.toString(), ex);
            }
            logger.error(ex.toString(), ex);
            return false;                                       
        }
    }
}
